import { Box3 } from "three";
import { Point } from "./Point";

/** 边界类 */
export default class Bounds extends Box3 {
    private southWest: Point;
    private northEast: Point;

    constructor(southWest: Point | Array<number>, northEast: Point | Array<number>) {
        super();
        if (southWest instanceof Array) {
            this.southWest = new Point(southWest[0], southWest[1], southWest[2] || 0);
        } else {
            this.southWest = southWest;
        }
        if (northEast instanceof Array) {
            this.northEast = new Point(northEast[0], northEast[1], northEast[2] || 0);
        } else {
            this.northEast = northEast;
        }
        let minVector = this.southWest.toVector3();
        let maxVector = this.northEast.toVector3();
        this.set(minVector, maxVector);
    }

    public contains(point: Point): boolean {
        let pointVector = point.toVector3();
        return this.containsPoint(pointVector);
    }

    public containsBounds(bound: Bounds) {
        return this.containsBox(bound);
    }
    /** 两个bound的交集 */
    public intersectBounds(bound: Bounds): Bounds {
        let istBox = super.intersect(bound);
        this.southWest = new Point().fromVector3(istBox.min);
        this.northEast = new Point().fromVector3(istBox.max);
        return this;
    }
    /**两个bound是否相交 */
    public isIntersect(bound: Bounds): boolean {
        let minlat = bound.getSouthWest().y;
        let minlng = bound.getSouthWest().x;
        let maxlat = bound.getNorthEast().y;
        let maxlng = bound.getSouthWest().x;

        if (this.contains(new Point(minlng, minlat)) ||
            this.contains(new Point(minlng, maxlat)) ||
            this.contains(new Point(maxlng, minlng)) ||
            this.contains(new Point(maxlng, maxlat))) {
            return true;
        }

        minlat = this.getSouthWest().y;
        minlng = this.getSouthWest().x;
        maxlat = this.getNorthEast().y;
        maxlng = this.getSouthWest().x;

        if (bound.contains(new Point(minlng, minlat)) ||
            bound.contains(new Point(minlng, maxlat)) ||
            bound.contains(new Point(maxlng, minlng)) ||
            bound.contains(new Point(maxlng, maxlat))) {
            return true;
        }

        return false;
    }

    /** 两个bound的并集 */
    public unionBounds(bound: Bounds): Bounds {
        let istBox = super.union(bound);
        this.southWest = new Point().fromVector3(istBox.min);
        this.northEast = new Point().fromVector3(istBox.max);
        return this;
    }

    /** 根据point扩大bound */
    public enlargeByPoint(point: Point) {
        super.expandByPoint(point.toVector3());
        this.southWest = new Point().fromVector3(this.min);
        this.northEast = new Point().fromVector3(this.max);
        return this;
    }

    public getCenter(): Point {
        let center = this.getCenter();
        let centerPoint = new Point().fromVector3(center);
        return centerPoint;
    }

    public getSouthWest(): Point {
        return this.southWest;
    }

    public getNorthEast(): Point {
        return this.northEast;
    }
    /** 获取边界的宽 */
    public getWidth(): number {
        if (this.max == undefined || this.min == undefined) return 0;
        let width = Math.abs(this.max.x - this.min.x);
        return width
    }
    /** 获取边界的高 */
    public getHeight(): number {
        if (this.max == undefined || this.min == undefined) return 0;
        let height = Math.abs(this.max.y - this.min.y);
        return height;
    }
    public toString(): string {
        return 'southWest:' + this.southWest + ',northEast:' + this.northEast;
    }

    public isEquals(bound: Bounds): boolean {
        return super.equals(bound);
    }
}